/*
 * Copyright (c) 2013-2018 上海汇数数据. All rights reserved.
 * @(#) I18nMessage.java 2018-08-06 12:29
 */

package cn.jh.common.core.i18n;

import org.jetbrains.annotations.Nullable;

import java.util.Locale;


/**
 * Strategy interface for resolving messages, with support for the parameterization
 * and internationalization of such messages.
 *
 * @author Fuchun
 * @since 1.0
 */
public interface I18nMessage {

    /**
     * Try to resolve the message. Return default message if no message was found.
     *
     * @param code the code to lookup up, such as 'plain.confirm'. Users of
     * this class are encouraged to base message names on the relevant fully
     * qualified class name, thus avoiding conflict and ensuring maximum clarity.
     * @param args array of arguments that will be filled in for params within
     * the message (params look like "{0}", "{1,date}", "{2,time}" within a message),
     * or {@code null} if none.
     * @param locale the Locale in which to do the lookup
     * @param defaultMessage String to return if the lookup fails
     * @return the resolved message if the lookup was successful;
     * otherwise the default message passed as a parameter
     */
    String getOrDefault(String code, @Nullable Object[] args, Locale locale, @Nullable String defaultMessage);

    /**
     * Try to resolve the message. Return default message if no message was found.
     *
     * @param code the code to lookup up, such as 'plain.confirm'. Users of
     * this class are encouraged to base message names on the relevant fully
     * qualified class name, thus avoiding conflict and ensuring maximum clarity.
     * @param locale the Locale in which to do the lookup
     * @param defaultMessage String to return if the lookup fails
     * @return the resolved message if the lookup was successful;
     * otherwise the default message passed as a parameter
     */
    default String getOrDefault(String code, Locale locale, String defaultMessage) {
        return getOrDefault(code, null, locale, defaultMessage);
    }

    /**
     * Try to resolve the default locale message. Return default message if no message was found.
     *
     * @param code the code to lookup up, such as 'plain.confirm'. Users of
     * this class are encouraged to base message names on the relevant fully
     * qualified class name, thus avoiding conflict and ensuring maximum clarity.
     * @param args array of arguments that will be filled in for params within
     * the message (params look like "{0}", "{1,date}", "{2,time}" within a message),
     * or {@code null} if none.
     * @param defaultMessage String to return if the lookup fails
     * @return the resolved message if the lookup was successful;
     * otherwise the default message passed as a parameter
     */
    default String getOrDefault(String code, @Nullable Object[] args, @Nullable String defaultMessage) {
        return getOrDefault(code, args, Locale.getDefault(), defaultMessage);
    }

    /**
     * Try to resolve the default locale message. Return default message if no message was found.
     *
     * @param code the code to lookup up, such as 'plain.confirm'. Users of
     * this class are encouraged to base message names on the relevant fully
     * qualified class name, thus avoiding conflict and ensuring maximum clarity.
     * @param defaultMessage String to return if the lookup fails
     * @return the resolved message if the lookup was successful;
     * otherwise the default message passed as a parameter
     */
    default String getOrDefault(String code, String defaultMessage) {
        return getOrDefault(code, (Object[]) null, defaultMessage);
    }

    /**
     * Resolve the message. Throw exception if no message was found.
     *
     * @param code the code to lookup up, such as 'plain.confirm'. Users of
     * this class are encouraged to base message names on the relevant fully
     * qualified class name, thus avoiding conflict and ensuring maximum clarity.
     * @param args array of arguments that will be filled in for params within
     * the message (params look like "{0}", "{1,date}", "{2,time}" within a message),
     * or {@code null} if none.
     * @param locale the Locale in which to do the lookup
     * @return the resolved message if the lookup was successful; otherwise throw Exception
     * @throws java.util.MissingResourceException if no object for the given code can be found
     */
    String get(String code, @Nullable Object[] args, Locale locale);

    String get(String code, Object[] args);

    /**
     * Resolve the message. Throw exception if no message was found.
     *
     * @param code the code to lookup up, such as 'plain.confirm'. Users of
     * this class are encouraged to base message names on the relevant fully
     * qualified class name, thus avoiding conflict and ensuring maximum clarity.
     * @param locale the Locale in which to do the lookup
     * @return the resolved message if the lookup was successful; otherwise throw Exception
     * @throws java.util.MissingResourceException if no object for the given code can be found
     */
    default String get(String code, Locale locale) {
        return get(code, null, locale);
    }

    /**
     * Resolve the default locale message. Throw exception if no message was found.
     *
     * @param code the code to lookup up, such as 'plain.confirm'. Users of
     * this class are encouraged to base message names on the relevant fully
     * qualified class name, thus avoiding conflict and ensuring maximum clarity.
     * @return the resolved message if the lookup was successful; otherwise throw Exception
     * @throws java.util.MissingResourceException if no object for the given code can be found
     */
    default String get(String code) {
        return get(code, null, Locale.getDefault());
    }
}
